home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / DJEMU106.ARJ / E17.CC < prev    next >
C/C++ Source or Header  |  1992-04-08  |  6KB  |  308 lines

  1. #include "emu.h"
  2. #include "rmov.h"
  3. #include "const.h"
  4.  
  5. extern "C" void djshld(void *);
  6. extern "C" void djshrd(void *);
  7.  
  8. int fprem_do(reg& quot, reg& div, int round) // remainder of st() / st(1)
  9. {
  10.   int rv;
  11.   int old_cw = control_word;
  12.   control_word &= ~CW_RC;
  13.   control_word |= round;
  14.   int expdif = quot.exp - div.exp;
  15.   if (expdif < 64)
  16.   {
  17.     reg tmp, tmp2;
  18.     r_div(quot, div, tmp);
  19.     long q;
  20.     r_mov(tmp, &q);
  21.     r_mov(&q, tmp);
  22.     r_mul(div, tmp, tmp2);
  23.     r_sub(quot, tmp2, tmp);
  24.     r_mov(tmp, quot);
  25.     rv = q & 7;
  26.   }
  27.   else
  28.   {
  29.     reg tmp, tmp2;
  30.     setcc(SW_C2);
  31.     r_div(st(), div, tmp);
  32.     int old_exp = tmp.exp;
  33.     tmp.exp &= 31;
  34.     long q;
  35.     r_mov(tmp, &q);
  36.     r_mov(&q, tmp);
  37.     tmp.exp = old_exp;
  38.     r_mul(div, tmp, tmp2);
  39.     r_sub(quot, tmp2, tmp);
  40.     r_mov(tmp, quot);
  41.     rv = -1;
  42.   }
  43.   control_word = old_cw;
  44.   return rv;;
  45. }
  46.  
  47. void fprem()
  48. {
  49.   if (empty(1))
  50.     return;
  51.   int q = fprem_do(st(), st(1), RC_CHOP);
  52.   if (q == -1)
  53.     setcc(SW_C2);
  54.   else
  55.   {
  56.     int c = 0;
  57.     if (q&4) c |= SW_C3;
  58.     if (q&2) c |= SW_C1;
  59.     if (q&1) c |= SW_C0;
  60.     setcc(c);
  61.   }
  62. }
  63.  
  64. void fyl2x();
  65.  
  66. void fyl2xp1()
  67. {
  68.   reg newx;
  69.   r_add(st(), CONST_1, newx);
  70.   r_mov(newx, st());
  71.   fyl2x();
  72.  
  73. #if 0
  74.   if (empty())
  75.     return;
  76.   reg frac2, sum, div, term, pow, temp;
  77.   r_mov(st(), frac2);
  78.   r_add(st(), CONST_2, div);
  79.   r_div(frac2, div, sum);
  80.   r_mul(sum, sum, frac2);
  81.   for (long i=3; i<15; i+=2)
  82.   {
  83.     r_mul(pow, frac2, temp);
  84.     r_mov(temp, pow);
  85.     r_mov(&i, div);
  86.     r_div(temp, div, term);
  87.     r_add(term, sum, temp);
  88.     r_mov(temp, sum);
  89.   }
  90.   r_div(sum, CONST_LN2, temp);
  91.   temp.exp++;
  92.   r_mul(temp, st(1), term);
  93.   r_mov(term, st(1));
  94.   st().tag = TW_E;
  95.   top++;
  96. #endif
  97. }
  98.  
  99. void fsqrt()
  100. {
  101.   if (empty())
  102.     return;
  103.   if (st().tag == TW_Z)
  104.     return;
  105.   if (st().exp == EXP_MAX)
  106.     return;
  107.   if (st().sign == SIGN_NEG)
  108.     return exception(EX_I);
  109.  
  110.   unsigned long long val = *(unsigned long long *)(&st().sigl);
  111.   unsigned long long result = 0;
  112.   unsigned long long side = 0;
  113.   unsigned long long left = 0;
  114.   int digit = 0;
  115.   int i;
  116.   if (st().exp & 1)
  117.   {
  118.     djshrd(&val);
  119.     st().exp++;
  120.   }
  121.   int exp = (st().exp - EXP_BIAS - 1)/2 - 64;
  122.   while (!(((long *)&result)[1] & 0x80000000))
  123.   {
  124. /*    left = (left << 2) + (val >> 62); */
  125.     left = (left << 2) + (((unsigned *)val)[1] >> 30);
  126.     djshld(&val);
  127.     djshld(&val);
  128.     if (left >= side*2 + 1)
  129.     {
  130.       left -= side*2+1;
  131.       side = (side+1)*2;
  132.       djshld(&result);
  133.       result |= 1;
  134.     }
  135.     else
  136.     {
  137.       side *= 2;
  138.       djshld(&result);
  139.     }
  140.     exp++;
  141.   }
  142.   st().exp = exp + EXP_BIAS;
  143.   st().sigl = result & 0xffffffff;
  144.   st().sigh = result >> 32;
  145.   st().tag = TW_V;
  146. }
  147.  
  148. void fsincos()
  149. {
  150.   if (empty())
  151.     return;
  152.   int q = fprem_do(st(), CONST_PI2, RC_CHOP);
  153.  
  154.   if (q & 1)
  155.   {
  156.     reg tmp;
  157.     r_sub(CONST_PI2, st(), tmp);
  158.     r_mov(tmp, st());
  159.   }
  160.  
  161.   reg x2, val, rv, tmp, t2;
  162.   reg valc, rvc, tmpc;
  163.   r_mov(st(), val);
  164.   r_mul(st(), val, x2);
  165.   r_mov(val, rv);
  166.   r_mov(CONST_1, valc);
  167.   r_mov(valc, rvc);
  168.  
  169.  
  170.   for (int i=0; i<11; i++)
  171.   {
  172.     val.sign ^= SIGN_POS ^ SIGN_NEG;
  173.     valc.sign ^= SIGN_POS ^ SIGN_NEG;
  174.     r_mul(x2, val, tmp);
  175.     r_mul(x2, valc, tmpc);
  176.     long c = ((i<<1)+2) * ((i<<1)+3);
  177.     r_mov(&c, t2);
  178.     r_div(tmp, t2, val);
  179.     c = ((i<<1)+1) * ((i<<1)+2);
  180.     r_mov(&c, t2);
  181.     r_div(tmpc, t2, valc);
  182.     r_add(val, rv, tmp);
  183.     r_mov(tmp, rv);
  184.     r_add(valc, rvc, tmpc);
  185.     r_mov(tmpc, rvc);
  186.   }
  187.   setcc(0);
  188.  
  189.   if (q & 2)
  190.     rv.sign ^= SIGN_POS ^ SIGN_NEG;
  191.   r_mov(rv, st());
  192.  
  193.   top--;
  194.   register int qq = q & 3;
  195.   if ((qq == 1) || (qq == 2))
  196.     rvc.sign ^= SIGN_POS ^ SIGN_NEG;
  197.   r_mov(rvc, st());
  198. }
  199.  
  200. void frndint()
  201. {
  202.   if (empty())
  203.     return;
  204.   long long tmp;
  205.   if (st().exp > EXP_BIAS+62)
  206.     return;
  207.   r_mov(st(), &tmp);
  208.   r_mov(&tmp, st());
  209. }
  210.  
  211. void fscale()
  212. {
  213.   long scale;
  214.   if (empty(1))
  215.     return;
  216.   r_mov(st(1), &scale);
  217.   st().exp += scale;
  218. }
  219.  
  220. void fsin()
  221. {
  222.   if (empty())
  223.     return;
  224.   int q = fprem_do(st(), CONST_PI2, RC_CHOP);
  225.  
  226.   if (q & 1)
  227.   {
  228.     reg tmp;
  229.     r_sub(CONST_PI2, st(), tmp);
  230.     r_mov(tmp, st());
  231.   }
  232.  
  233.   reg x2, val, rv, tmp, t2;
  234.   r_mov(st(), val);
  235.   r_mul(st(), val, x2);
  236.   r_mov(val, rv);
  237.  
  238.  
  239.   for (int i=0; i<11; i++)
  240.   {
  241.     long c = ((i<<1)+2) * ((i<<1)+3);
  242.     val.sign ^= SIGN_POS ^ SIGN_NEG;
  243.     r_mul(x2, val, tmp);
  244.     r_mov(&c, t2);
  245.     r_div(tmp, t2, val);
  246.     r_add(val, rv, tmp);
  247.     r_mov(tmp, rv);
  248.   }
  249.   setcc(0);
  250.   if (q & 2)
  251.     rv.sign ^= SIGN_POS ^ SIGN_NEG;
  252.   r_mov(rv, st());
  253. }
  254.  
  255. void fcos()
  256. {
  257.   if (empty())
  258.     return;
  259.   int q = fprem_do(st(), CONST_PI2, RC_CHOP);
  260.  
  261.   if (q & 1)
  262.   {
  263.     reg tmp;
  264.     r_sub(CONST_PI2, st(), tmp);
  265.     r_mov(tmp, st());
  266.   }
  267.  
  268.   reg x2, val, rv, tmp, t2;
  269.   r_mov(st(), val);
  270.   r_mul(st(), val, x2);
  271.   r_mov(CONST_1, val);
  272.   r_mov(val, rv);
  273.  
  274.  
  275.   for (int i=0; i<11; i++)
  276.   {
  277.     long c = ((i<<1)+1) * ((i<<1)+2);
  278.     val.sign ^= SIGN_POS ^ SIGN_NEG;
  279.     r_mul(x2, val, tmp);
  280.     r_mov(&c, t2);
  281.     r_div(tmp, t2, val);
  282.     r_add(val, rv, tmp);
  283.     r_mov(tmp, rv);
  284.   }
  285.   setcc(0);
  286.   register int qq = q & 3;
  287.   if ((qq == 1) || (qq == 2))
  288.     rv.sign ^= SIGN_POS ^ SIGN_NEG;
  289.   r_mov(rv, st());
  290. }
  291.  
  292. FUNC emu_17_table[] = {
  293.   fprem, fyl2xp1, fsqrt, fsincos, frndint, fscale, fsin, fcos
  294. };
  295.  
  296. void emu_17()
  297. {
  298.   if (modrm > 0277)
  299.   {
  300.     (emu_17_table[modrm&7])();
  301.   }
  302.   else
  303.   {
  304.     // fstcw m16int
  305.     *(short *)get_modrm() = control_word;
  306.   }
  307. }
  308.